import re
import requests
from lxml import etree
from enum import Enum
from ai import AiConstant
from ai.utils import utils_file
import traceback
import project_config

log_path = utils_file.join_path(AiConstant.LOG_PATH, project_config.PROJECT_NAME, 'ximalaya.log')

logger = AiConstant.AI_LOGGER(log_path)


def if_response_content_is_none(response):
    if response.content is None:
        logger.info('response.content为None,加载数据失败')
        return True
    return False


def write_to_html(data, file_name):
    with open(file_name, 'w', encoding='utf-8') as f:
        f.write(data)


def get_ids(datas):
    """
    datas: [strs]:str_list or str:str
    return : [ids]:list
    """
    if isinstance(datas, list):
        return [x.split('/')[-1] for x in datas]
    elif isinstance(datas, str):
        return [datas.split('/')[-1]]


class REQUEST_METHOD(Enum):
    GET = 1
    POST = 2


def send_request(src, headers, method: REQUEST_METHOD = REQUEST_METHOD.GET):
    """
    发送请求, 如果顺利得到response并没有爆出任何错误,同时状态码为200, 则正常返回, 否则给出失败提示,
    需要调用者自行决定是否进行成功提示, 该函数不提供
    """
    response = None
    try:
        if method == REQUEST_METHOD.GET:
            response = requests.get(src, headers=headers)
        elif method == REQUEST_METHOD.POST:
            response = requests.post(src, headers=headers)
        if not hasattr(response, 'status_code'):
            raise RuntimeError()
        if not (response.status_code == 200 or response.status_code == 206):
            raise RuntimeError()
    except Exception as e:
        if hasattr(response, 'status_code'):
            logger.error(f"请求失败{e},code:{response.status_code}")
        else:
            logger.error(f"请求失败{e}")
        traceback.print_exc()
        return None
    return response


def handle_xpath(html_text: str, xpath):
    try:
        tree = etree.HTML(html_text)
        datas = tree.xpath(xpath)
        if len(datas) == 0 or len(datas[-1]) == 0:
            raise RuntimeError()
        return datas
    except Exception as e:
        logger.info('xpath处理失败')
        return None


def sub_handle_xpath(tree, xpath):
    try:
        datas = tree.xpath(xpath)
        if len(datas) == 0 or len(datas[-1]) == 0:
            raise RuntimeError()
        return datas
    except Exception as e:
        logger.info('xpath处理失败')
        return None


def join_path(path1, path2):
    if path1 is None or path2 is None or len(path1) == 0 or len(path2) == 0:
        return ""
    while path1[-1] == '/' or path1[-1] == '\\':
        path1 = path1[:-1]
    while path2[0] == '/' or path2[0] == '\\':
        path2 = path2[1:]
    return f'{path1}/{path2}'


def join_path_plus(*args):
    lens = len(args)
    if lens == 0:
        return ""
    path = args[0]
    for i in range(1, lens):
        path = join_path(path, args[i])
    return path


def clean_filename(filename):
    # 移除非法字符
    cleaned_filename = re.sub(r'[\/:*?"<>|]', '-', filename)
    # 截断文件名，以确保它在不同系统下都有效
    cleaned_filename = cleaned_filename[:255]
    return cleaned_filename


class FileType(Enum):
    HTML = 1,
    XML = 2,


def text2special_file(text, file_type: FileType = FileType.HTML):
    if file_type == FileType.HTML:
        try:
            tree = etree.HTML(text)
        except Exception as e:
            logger.info('text->html失败')
            return None
        return tree


def if_json_data_is_none(json_data):
    if json_data is None:
        logger.info('json_data is None, 未获取到json数据')
        return True
    return False


def get_name_by_rules(id, album_id, title, with_album_id, with_title):
    adds = []
    if with_album_id:
        adds.append(album_id)
    if with_title:
        title = clean_filename(title)
        adds.append(title)
    name = str(id)
    for item in adds:
        name = name + '_' + item
    name = name + '.wav'
    return name
